use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{BufReader, BufRead};

#[derive(Debug)]
// 定义元祖结构体，只有一个元素，可通过索引0直接访问
struct WordCounter(HashMap<String, u64>);

// 给元祖结构体添加方法
impl WordCounter {
    // 初始化方法，给内部元素hashmap初始化，返回实例
    fn new() -> WordCounter {
        WordCounter(HashMap::new())
    }
    // 累加方法 先从hashmap中获取word个数，没有返回0，在加1
    fn increment(&mut self, word: &str) {
        let key = word.to_string();
        // 获取word个数的可变引用，存的是地址
        // 可变是因为参数&mut self
        let count = self.0.entry(key).or_insert(0);
        // 引用不能直接加1，要解引用，通过地址获取参考，即实际的值
        *count += 1;
    }
    // 展示方法 通过遍历，打印详情
    fn display(&self) {
        for (k, v) in self.0.iter() {
            println!("{} -> {}", k, v);
        }
    }
}

// 在项目路径下执行：cargo run file_path
fn main() {
    // 将出入的参数转换为一个列表
    let args: Vec<String> = env::args().collect();
    // 获取列表中索引为1的参数，索引为0的参数表示程序名称
    let file_name = &args[1];
    println!("Processing filepath: {}", file_name);

    let file = File::open(file_name).expect("Could not open file");
    let reader = BufReader::new(file);
    let mut word_counter = WordCounter::new();

    for line in reader.lines() {
        let line = line.expect("Could not read line");
        let words = line.split(" ");

        for word in words {
            if word.is_empty() {
                continue;
            } else {
                word_counter.increment(word);
            }
        }
    }

    word_counter.display();
}
